/**
 * 处理 全局钩子队列
 * @param {Object} to
 * @param {Function} uniRunRoute 被hack的uniapp路由方法
 */
export const handleGlobalHooksQueue = function(to, uniRunRoute) {
	// 获取当前路由栈信息
	const from = getCurStack();
	// 路由返回时为to赋值
	if (!to.url) {
		to.url = getCurStack(1).url
	}
	iteratorHook(
		this.beforeHooks,
		handleNextPipe.bind(this),
		() => {
			uniRunRoute();
			handleAfterHook.call(this, to, from);
		}, {
			to,
			from,
			uniRunRoute
		}
	);
};

/**
 * 处理 全局后置钩子
 * @param {Object} to
 * @param {Object} from
 */
const handleAfterHook = function(to, from) {
	this.afterHooks.forEach((hook) => {
		hook(to, from);
	});
};

/**
 * 处理 错误信息
 * @param {Object|string} err 错误信息、错误栈
 */
const handleAbort = function(err) {
	if (this.errorCbs.length > 0) {
		this.errorCbs.forEach((cb) => {
			cb(err);
		});
	} else {
		print('error:' + err, 'error');
	}
};

/**
 * 遍历并运行 钩子
 * @param {Function[]} hookQueue 钩子队列
 * @param {Function} everyCb 每次遍历都会运行的回调函数
 * @param {Function} endCb 队列运行结束后运行的回调函数
 * @param {Object} hookOpts 钩子运行需要的参数
 */
const iteratorHook = function(hookQueue, everyCb, endCb, hookOpts) {
	const next = (i) => {
		// 队列运行结束，运行回调函数
		if (i >= hookQueue.length) {
			endCb.call(this);
		} else {
			// 遍历运行钩子
			everyCb.call(this, hookQueue[i], hookOpts, (val) => {
				// 结束钩子遍历
				if (val === false) return;
				next(++i);
			});
		}
	};

	next(0);
};

/**
 * 处理 有next参数的钩子(前置钩子)
 * @param {Function} hookCb 钩子函数
 * @param {Object} hookOpts 钩子运行需要的参数
 * @param {Function} iteratorNextHook 运行下一个钩子
 */
const handleNextPipe = function(hookCb, hookOpts, iteratorNextHook) {
	hookCb(hookOpts.to, hookOpts.from, (nextVal) => {
		try {
			// next(false) or next(new Error('xxx')) 中断当前的路径跳转，或中断且注册错误回调
			if (nextVal === false || isError(nextVal)) {
				handleAbort.call(this, nextVal);
			}

			// next('/pages/a') or next({ url: '/pages/a' }) 修改 路由
			else if (
				typeof nextVal === 'string' ||
				(typeof nextVal === 'object' && typeof nextVal.url === 'string')
			) {
				// 处理字符串路径
				typeof nextVal === 'string' && (nextVal = {
					url: nextVal
				});

				hookOpts.uniRunRoute(nextVal);
				handleAfterHook.call(this, hookOpts.to, hookOpts.from);

				// 更新引用，替换原来的`url`字段数据
				hookOpts.to = Object.assign(hookOpts.to, nextVal);

				// 结束钩子遍历
				iteratorNextHook(false);
			}

			// next() 运行下一个管道(next)
			else {
				iteratorNextHook();
			}
		} catch (err) {
			handleAbort.call(this, err);
		}
	});
};


export const print = function(msg, action = 'log') {
	console[action]('[route-guards] ' + msg);
};

/**
 * 判断错误对象是否是由`Error`对象实例化出来的
 * @param {Error|Object} errObj
 * @return {boolean}
 */
export const isError = function(errObj) {
	return Object.prototype.toString.call(errObj).includes('Error');
};

/**
 * 获取并封装当前路由栈的信息
 * @return {Object}
 */
export const getCurStack = function(index = 0) {
	const stackAll = getCurrentPages();
	const stackLen = stackAll.length;

	// 跳过路由栈为空的情况(App端)
	if (stackLen === 0) {
		return false;
	}

	const curStack = stackAll[stackLen - 1 - index];
	let from = ''
	if (curStack) {
		from = {
			url: '/' + curStack.route
		};
	}


	return from;
};

// 路由监听
export const listenRoute = function(track) {
	const currentPath = {
		query: this.$mp.query,
		route: this.$mp.page.route
	}
	let list = getApp().globalData.pageStackList || []
	if (list.length) {
		try {
			const stackAll = getCurrentPages();
			const stackLen = stackAll.length;
			let params = currentPath.query
			let toUrl = currentPath.route
			let actions = ''
			let fromUrl = ''
			let switchTabs = ['pages/index/index', 'pages/reading/index', 'pages/message/message', 'pages/mine/mine']
			if (stackLen < list.length) {
				actions = 'navigateBack'
				let last = list.pop();
				fromUrl = last.route
			} else if (switchTabs.includes(stackAll[stackLen - 1].route)) {
				actions = 'switchTab'
				fromUrl = list[list.length - 1].route
				list[list.length - 1] = currentPath
			} else if (stackLen > list.length) {
				actions = 'navigateTo'
				fromUrl = stackAll[stackLen - 2].route
				list.push(currentPath)
			} else if (stackLen == list.length) {
				actions = 'redirectTo'
				if (stackAll[stackLen - 1].route !== list[list.length - 1].route) {
					fromUrl = list[list.length - 1].route
				} else {
					fromUrl = stackAll[stackLen - 1].route
				}
				list[list.length - 1] = currentPath
			}
			track.track({
				path: '/' + fromUrl,
				type: 'router',
				desc: '路由跳转',
				data: {
					'to_path': '/' + toUrl,
					'to_params': JSON.stringify(params),
					'router_type': actions
				}
			})

			// wx.reportAnalytics('route', {
			// 	"from": fromUrl,
			// 	"to": toUrl,
			// 	"query": JSON.stringify(params),
			// });
			if (fromUrl == 'pages/index/index') {
				// 阿拉丁事件上传
				wx.aldstat && wx.aldstat.sendEvent(toUrl, {
					"params": JSON.stringify(params),
					'type': actions
				})
			}

			//漏斗埋点
			if (toUrl === 'pages/index/ask/ask') {
				wx.aldstat && wx.aldstat.sendEvent('从所有入口进入一问多诊主页的pv', {
					"params": JSON.stringify(params),
					'type': actions
				})
			}
			if (toUrl === 'pages/index/ask/main/main') {
				wx.aldstat && wx.aldstat.sendEvent('一问多诊订单信息填写页的pv', {
					"params": JSON.stringify(params),
					'type': actions
				})
			}
			if (fromUrl == 'pages/index/ask/main/main' && toUrl === 'pages/index/ask/pay/pay') {
				wx.aldstat && wx.aldstat.sendEvent('点击提交问题后跳转的支付页面的pv', {
					"params": JSON.stringify(params),
					'type': actions
				})
			}
			if (toUrl === 'pages/index/ask/pay/payResult') {
				wx.aldstat && wx.aldstat.sendEvent('支付成功数', {
					"params": JSON.stringify(params),
					'type': actions
				})
			}
			if (toUrl === 'subInquiry/pages/index') {
				wx.aldstat && wx.aldstat.sendEvent('从所有入口进入远程问诊主页的pv', {
					"params": JSON.stringify(params),
					'type': actions
				})
			}
			if (toUrl === 'subInquiry/pages/doctorHome/doctorHome') {
				wx.aldstat && wx.aldstat.sendEvent('所有医生主页的pv', {
					"params": JSON.stringify(params),
					'type': actions
				})
			}
			if (toUrl === 'subInquiry/pages/submitorder/index') {
				wx.aldstat && wx.aldstat.sendEvent('远程问诊订单填写页面的pv', {
					"params": JSON.stringify(params),
					'type': actions
				})
			}
			if (toUrl === 'subInquiry/pages/pay/index') {
				wx.aldstat && wx.aldstat.sendEvent('点击提交到支付页面的pv', {
					"params": JSON.stringify(params),
					'type': actions
				})
			}
			if (toUrl === 'subInquiry/pages/pay/result/index') {
				wx.aldstat && wx.aldstat.sendEvent('支付成功数', {
					"params": JSON.stringify(params),
					'type': actions
				})
			}


		} catch (e) {
			//TODO handle the exception
		}
	} else {
		list.push(currentPath)
	}

	getApp().globalData.pageStackList = list
}
